import config from './config';
import Message from './message';
import network from './network';
import Subject from './subject';


class BubbleInfo {
    constructor(info) {
        this.senderId = info.sender_id;
        this.text = info.text;
        this.time = info.time;
    }
}

class UserInfo {
    constructor(info) {
        this.uid = info.uid;
        this.name = info.name;
        this.headId = info.head_id;
    }
}

class RoomInfo {
    constructor(info) {
        this.userList = [];
        this.bubbleList = [];

        for (let i = 0; i < info.user_list.length; i++) {
            this.userList.push(new UserInfo(info.user_list[i]));
        }
        for (let i = 0; i < info.bubble_list.length; i++) {
            this.bubbleList.push(info.bubble_list[i]);
        }
    }
    arriveBubble(bubbleInfo) {
        this.bubbleList.push(bubbleInfo);
    }
    addUser(userInfo) {
        let user = new UserInfo(userInfo);
        this.userList.push(user);
    }
    delUser(uid) {
        for (let i = 0; i < this.userList.length; i++) {
            if (this.userList[i].uid == uid) {
                return this.userList.splice(i, 1)[0];
            }
        }
    }
}

class LocalStorage {
    constructor(name) {
        this.name = name;
        this.data = {};
    }
    load() {
        this.data = {};
        try {
            let str = window.localStorage.getItem(this.name);
            if (str) {
                let data = JSON.parse(str);
                Object.assign(this.data, data);
            }
        } catch (e) {
            e;
        }
    }
    save() {
        let str = JSON.stringify(this.data);
        window.localStorage.setItem(this.name, str);
    }
    clear() {
        this.data = {};
        window.localStorage.removeItem(this.name);
    }

    get(key, val) {
        if( !this.has(key ) ){
            this.set( key, val || null );
        }
        return this.data[key];
    }

    set(key, val) {
        this.data[key] = val;
    }

    has(key) {
        return !!this.data[key];
    }
    del( key ) {
        delete this.data[key];
    }
}

class CacheData extends Subject {
    constructor() {
        super();

        this.localStorage = new LocalStorage(config.localStorageName);
        this.localStorage.load();

        this.__blockerCount = 0;
        this.__app = null;

        this.userInfo = null;
        this.isLogged = false;

        this.roomInfo = null;
        this.hasRoom = false;

        network.on("onMessage", this.onMessage, this);
    }
    reset() {
        this.userInfo = null;
        this.isLogged = false;
        this.roomInfo = null;
        this.hasRoom = false;
    }
    set app(val) {
        this.__app = val;
    }
    get app() {
        return this.__app;
    }
    set blockerCount(val) {
        this.__blockerCount = val;
        this.emit("onBlockerCountChange", this.__blockerCount);
    }
    get blockerCount() {
        return this.__blockerCount;
    }
    onMessage(msg) {
        switch (msg.type) {
            case Message.Type.MCError:
                console.log("---error:", msg.data);
                this.emit("onError");
                break;
            case Message.Type.MCLoginGuest:
                this.userInfo = new UserInfo(msg.data.user_info);
                this.isLogged = true;
                this.emit("onLogin");
                break;
            case Message.Type.MCLogout:
                this.reset();
                // this.userInfo = null;
                // this.isLogged = false;
                // this.roomInfo = null;
                // this.hasRoom = false;
                this.emit("onLogout");
                break;
            case Message.Type.MCUserIn:
                if (msg.data.user_info.uid == this.userInfo.uid) {
                    this.hasRoom = true;
                    this.emit("onRoomIn");
                }
                else {
                    this.roomInfo.addUser(msg.data.user_info);
                }
                this.app.updateUserCount();
                break;
            case Message.Type.MCUserOut:
                if (msg.data.user_info.uid == this.userInfo.uid) {
                    this.roomInfo = null;
                    this.hasRoom = false;
                    this.emit("onRoomOut");
                }
                else {
                    this.roomInfo.delUser(msg.data.user_info.uid);
                }
                this.app.updateUserCount();
                break;
            case Message.Type.MCRoomInfo:
                this.roomInfo = new RoomInfo(msg.data.room_info);
                this.emit("onRoomInfo");
                this.app.updateUserCount();
                break;
            case Message.Type.MCAddBubble:
            case Message.Type.MCArriveBubble:
                {
                    let bubble_info = msg.data.bubble_info;
                    let bubbleInfo = new BubbleInfo(bubble_info);
                    this.emit("onArriveBubble", bubbleInfo);
                    this.roomInfo.arriveBubble(bubbleInfo);
                }
                break;
        }
    }
}

var cacheData = new CacheData();
export default cacheData;